package cronTask

import (
	"github.com/pkg/errors"
	"github.com/robfig/cron/v3"
	"shop-common/engine"
	"sync"
)

//定时任务调度器
type Scheduler struct {
	inner *cron.Cron
	ids   map[string]cron.EntryID
	mutex sync.Mutex
}

// new新的定时任务引擎
func NewScheduler() *Scheduler {
	// Scheduler.New() 默认从分开始，cronTask.WithSeconds() 加上后默认从秒开始
	return &Scheduler{inner: cron.New(cron.WithSeconds()), ids: map[string]cron.EntryID{}}
}

// 引擎开始
func (c *Scheduler) Start() {
	c.inner.Start()
}

// 停止引擎
func (c *Scheduler) Stop() {
	c.inner.Stop()
}

/**
 * 删除任务
 * @param id 唯一任务id
 */
func (c *Scheduler) DelByID(id string) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	eid, ok := c.ids[id]
	if !ok {
		return
	}
	c.inner.Remove(eid)
}

/**
 * 实现接口的方式添加定时任务
 * @param id 唯一任务id
 * @param spec 配置定时执行时间
 * @param cj 需要执行的任务方法
 * @return error
 */
func (c *Scheduler) AddJobByInterface(id string, spec string, cj cron.Job) error {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	if _, ok := c.ids[id]; ok {
		return errors.Errorf("crontab id exists")
	}
	eid, err := c.inner.AddJob(spec, cj)
	if err != nil {
		return err
	}
	c.ids[id] = eid
	return nil
}

/**
 * 添加函数作为定时任务
 * @param id 唯一任务id
 * @param spec 配置定时执行时间
 * @param f 需要执行的方法
 * @return error
 */
func (c *Scheduler) AddJobByFunc(cron *engine.CronJob) error {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	if _, ok := c.ids[cron.Name]; ok {
		return errors.Errorf("crontab id exists")
	}
	eid, err := c.inner.AddFunc(cron.Spec, cron.Job)
	if err != nil {
		return err
	}
	c.ids[cron.Name] = eid
	return nil
}

/**
 * 判断是否存在任务
 * @param id 唯一任务id
 * @return bool
 */
func (c *Scheduler) IsExistsJob(id string) bool {
	_, exist := c.ids[id]
	return exist
}
